package com.shanzmoo.merchant.server.api.manager.integral;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.shanzmoo.base.util.CollectionUtil;
import com.shanzmoo.db.module.integral.domain.dto.IntegralOrderGoodsDto;
import com.shanzmoo.db.module.integral.domain.dto.IntegralOrderInfoDto;
import com.shanzmoo.db.module.integral.domain.dto.IntegralOrderSaveDto;
import com.shanzmoo.db.module.integral.domain.vo.IntegralOrderGoodsVo;
import com.shanzmoo.db.module.integral.domain.vo.IntegralOrderVo;
import com.shanzmoo.db.module.integral.entity.IntegralOrderEntity;
import com.shanzmoo.db.module.integral.entity.IntegralOrderGoodsEntity;
import com.shanzmoo.db.module.integral.service.IIntegralOrderGoodsService;
import com.shanzmoo.db.module.integral.service.IIntegralOrderService;
import com.shanzmoo.db.module.member.entity.MemberAddressEntity;
import com.shanzmoo.db.module.member.entity.MemberCouponConfigEntity;
import com.shanzmoo.db.module.member.entity.MemberCouponEntity;
import com.shanzmoo.db.module.member.service.IMemberActivityConfigService;
import com.shanzmoo.db.module.member.service.IMemberAddressService;
import com.shanzmoo.db.module.member.service.IMemberCouponConfigService;
import com.shanzmoo.db.module.member.service.IMemberCouponService;
import com.shanzmoo.db.module.merchant.entity.MerchantShopEntity;
import com.shanzmoo.db.module.merchant.service.IMerchantShopService;
import com.shanzmoo.db.module.product.entity.ProductSkuEntity;
import com.shanzmoo.db.module.product.entity.ProductSpuEntity;
import com.shanzmoo.db.module.product.service.IProductSkuService;
import com.shanzmoo.db.module.product.service.IProductSpuService;
import com.shanzmoo.merchant.server.api.util.SecurityUtil;
import com.shanzmoo.pay.domain.response.payResponse.SaobeiJsPayResponse;
import com.shanzmoo.pay.manager.SaobeiPayManager;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * @author fs
 * 权益订单manager
 */
@Component
@RequiredArgsConstructor
public class IntegralOrderManager {
    private final IIntegralOrderService iIntegralOrderService;
    private final IIntegralOrderGoodsService iIntegralOrderGoodsService;
    private final IMemberAddressService iMemberAddressService;
    private final IMerchantShopService iMerchantShopService;
    private final IProductSkuService iProductSkuService;
    private final IProductSpuService iProductSpuService;
    private final IMemberCouponService iMemberCouponService;
    private final IMemberCouponConfigService iMemberCouponConfigService;
    private final IMemberActivityConfigService iMemberActivityConfigService;
    private final SaobeiPayManager saobeiPayManager;

    /**
     * 创建订单
     * @param param
     * @return
     */
    public IntegralOrderVo createOrder(IntegralOrderSaveDto param){
        IntegralOrderVo orderVo = new IntegralOrderVo();
        orderVo.setPromotionPrice(0);
        orderVo.setFreight(0);
        orderVo.setGoodsPrice(0);
        orderVo.setCouponPrice(0);
        orderVo.setIntegralPrice(0);
        orderVo.setRefundFee(0);
        //地址
        if(param.getAddrId() != null){
            MemberAddressEntity addressEntity = iMemberAddressService.getById(param.getAddrId());
            Assert.notNull(addressEntity,"当前用户地址不存在");
            orderVo.setAddr(addressEntity.getAddress());
            orderVo.setReviceName(addressEntity.getContacts());
            orderVo.setRevicePhone(addressEntity.getMobile());
        }
        //门店
        if(StrUtil.isNotBlank(param.getShopCode())){
            MerchantShopEntity shopEntity = iMerchantShopService.
                    lambdaQuery().
                    eq(MerchantShopEntity::getCode,param.getShopCode())
                    .one();
            Assert.notNull(shopEntity,"当前店铺不存在");
            orderVo.setShopCode(shopEntity.getCode());
            orderVo.setShopName(shopEntity.getName());
        }
        //商品
        if(CollUtil.isNotEmpty(param.getGoods())){
            List<IntegralOrderGoodsDto> goods = param.getGoods();
            int goodsPrice = 0;
            int goodsTotal= 0;
            List<IntegralOrderGoodsVo> goodsList = new ArrayList<>();
            for(IntegralOrderGoodsDto goodsDto:goods){
                goodsTotal += goodsDto.getNums();
                ProductSkuEntity skuEntity = iProductSkuService.getById(goodsDto.getSkuId());
                Assert.notNull(skuEntity,"当前商品sku不存在");
                ProductSpuEntity spuEntity = iProductSpuService.getById(skuEntity.getParentId());
                Assert.notNull(skuEntity,"当前商品不存在");
                IntegralOrderGoodsVo goodsVo = new IntegralOrderGoodsVo();
                goodsVo.setSkuId(skuEntity.getId());
                goodsVo.setSpuId(spuEntity.getId());
                goodsVo.setNums(goodsDto.getNums());
                goodsVo.setPrice(NumberUtil.mul(skuEntity.getPrice(),100).intValue());
                goodsVo.setImgUrl("");
                goodsVo.setName(spuEntity.getName());
                goodsVo.setSkuName(skuEntity.getAttributeDesc());
                goodsList.add(goodsVo);
            }
            orderVo.setGoods(goodsList);
            orderVo.setGoodsTotal(goodsTotal);
            orderVo.setGoodsPrice(goodsPrice);
        }
        //发票四项
        if(StrUtil.isNotBlank(param.getInvoiceDetail())){
            orderVo.setInvoiceDetail(param.getInvoiceDetail());
        }
        if(StrUtil.isNotBlank(param.getInvoiceNo())){
            orderVo.setInvoiceNo(param.getInvoiceNo());
        }
        if(StrUtil.isNotBlank(param.getInvoiceName())){
            orderVo.setInvoiceName(param.getInvoiceName());
        }
        if(StrUtil.isNotBlank(param.getInvoiceType())){
            orderVo.setInvoiceType(param.getInvoiceType());
        }
        //备注
        if(StrUtil.isNotBlank(param.getRemark())){
            orderVo.setRemark(param.getRemark());
        }
        //优惠券
        if(param.getCouponId() != null){
            MemberCouponEntity couponEntity = iMemberCouponService.getById(param.getCouponId());
            Assert.notNull(couponEntity,"当前优惠券不存在");
            Assert.isTrue(StrUtil.equals(Convert.toStr(SecurityUtil.getCurrentUserId()),couponEntity.getMemberId()),"当前优惠券非你所有");
            Assert.isTrue(couponEntity.getStatus() == 1,"当前优惠券无法使用");
            MemberCouponConfigEntity couponConfigEntity = iMemberCouponConfigService.getById(couponEntity.getCouponConfigId());
            Assert.notNull(couponConfigEntity,"当前优惠券配置不存在");
            Assert.isTrue(couponConfigEntity.getStatus() == 1,"当前优惠券没生效");
            Assert.isTrue(couponConfigEntity.getStartTime().isBefore(LocalDateTime.now()),"当前优惠券没开始");
            Assert.isTrue(couponConfigEntity.getEndTime().isAfter(LocalDateTime.now()),"当前优惠券已过期");
            orderVo.setCouponId(couponEntity.getId());
            Assert.isTrue(orderVo.getGoodsTotal()>=couponConfigEntity.getRuleFull(),"当前金额不足以使用优惠券");
            String couponName = "";
            if(couponConfigEntity.getType() == 1){
                //满减
                String ruleFull = NumberUtil.decimalFormat("#0.00",NumberUtil.div(couponConfigEntity.getRuleFull(),(Number) 100));
                String ruleSubtract = NumberUtil.decimalFormat("#0.00",NumberUtil.div(couponConfigEntity.getRuleSubtract(),(Number) 100));
                couponName = "满"+ruleFull+"元减"+ruleSubtract+"元";
                orderVo.setCouponPrice(Convert.toInt(couponConfigEntity.getRuleSubtract()));
            }else if(couponConfigEntity.getType() == 1){
                //折扣
                String ruleFull = NumberUtil.decimalFormat("#0.00",NumberUtil.div(couponConfigEntity.getRuleFull(),(Number) 100));
                String ruleSubtract = NumberUtil.decimalFormat("#0.0",NumberUtil.div(couponConfigEntity.getRuleSubtract(),(Number) 10));
                couponName = "满"+ruleFull+"元打"+ruleSubtract+"折";
                BigDecimal bl = NumberUtil.div(100-couponConfigEntity.getRuleSubtract(),(Number) 100);
                orderVo.setCouponPrice(NumberUtil.mul(orderVo.getGoodsTotal(),bl).intValue());
            }
            orderVo.setCouponName(couponName);
        }
        //TODO 运费和活动费
        orderVo.setPromotionPrice(0);
        orderVo.setFreight(0);
        orderVo.setOrderPrice(
                orderVo.getGoodsPrice()
                        -orderVo.getCouponPrice()
                        -orderVo.getPromotionPrice()
                        +orderVo.getFreight()
                        -orderVo.getIntegralPrice()
        );
        orderVo.setUserId(SecurityUtil.getCurrentUserId());
        orderVo.setPromotionIds("");
        orderVo.setStatus(0);
        //TODO 订单类型
        orderVo.setOrderType(0);
        return orderVo;
    }

    /**
     * 保存订单
     * @param param
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public IntegralOrderVo saveOrder(IntegralOrderSaveDto param){
        IntegralOrderVo data = createOrder(param);
        //TODO 订单编号
        data.setOrderNo("");
        data.setOrderTime(LocalDateTime.now());
        IntegralOrderEntity entity = data.convert(IntegralOrderEntity.class);
        iIntegralOrderService.save(entity);
        data.setId(entity.getId());
        List<IntegralOrderGoodsVo> goodsList = data.getGoods();
        for(IntegralOrderGoodsVo goodsVo:goodsList){
            IntegralOrderGoodsEntity goodsEntity = goodsVo.convert(IntegralOrderGoodsEntity.class);
            goodsEntity.setOrderId(entity.getId());
            iIntegralOrderGoodsService.save(goodsEntity);
        }
        return data;
    }

    public IntegralOrderVo orderInfo(IntegralOrderInfoDto param) {
        IntegralOrderEntity entity = iIntegralOrderService.getById(param.getId());
        Assert.notNull(entity,"当前订单不存在");
        IntegralOrderVo vo = entity.convert(IntegralOrderVo.class);
        List<IntegralOrderGoodsEntity> goodsList = iIntegralOrderGoodsService.lambdaQuery().eq(IntegralOrderGoodsEntity::getOrderId,param.getId()).list();
        List<IntegralOrderGoodsVo> goodsVos = CollectionUtil.convert(goodsList,IntegralOrderGoodsVo.class);
        vo.setGoods(goodsVos);
        return vo;
    }

    public IntegralOrderVo payOrder(IntegralOrderInfoDto param) {
        IntegralOrderVo orderVo = orderInfo(param);
        SaobeiJsPayResponse response = saobeiPayManager.addPayOrder(orderVo.convert(IntegralOrderEntity.class),"","",param.getPayType());
        orderVo.setPayResponse(response);
        return orderVo;
    }
}
